///
/// Author: Greg Sandstrom
/// Email: greg.sandstrom@gmail.com
/// Class: CSCI-399
/// Date: 03/24/2008
/// Lab: 2 (Ringtone Lab)
/// IDE: ZDS II - ZNEO 4.11.1 (Build 08081801)
/// Description: Listens on the Serial Port for a RTTL string, Button 3 plays it.
///	  Button 1 & 2 play stored strings.
///
///   Serial Port at 57600
///   Speaker on PC[0-1]
///   Status LEDs on PF[0-3]
///
/// Problems: Getting the note duration/beats per minute working.  Some samples seem too slow, some seem way too fast.
///  I think I must be missing something
///  Getting the UART to operate in interrupt mode.

#include <zneo.h>

#include "clock.h"
#include "led.h"
#include "ledmatrix.h"

#include "uart_rx_interrupt.h"
#include "rttl_timer.h"
#include "rttl_play.h"
#include "rttl_samples.h"

void main_loop(void);

void main() {
	int i;

	DI();

	InitSystemClock();

	InitLEDs();
	InitLEDMatrixes();

	ClearLEDMatrix(0);

	init_uart();

	init_timer0();
	init_timer1();

	EI();

	//play_scale();

	i = 0;

	while (1) {
		main_loop();
	}
}


#define BUFFER_SIZE 255

#define READING 0x00
#define PLAYING 0x02

short volatile read_mode = READING;

char buffer[BUFFER_SIZE];
int volatile offset = 0;

#pragma interrupt
void interrupt uart0_rx_isr(void) {
	char c;
	SET_VECTOR(UART0_RX, uart0_rx_isr);

	// read to clear the read bit
	c = U0RXD;

	// if we are currently reading
	if (read_mode == READING) {
		SetLEDs(offset);

		if (offset < BUFFER_SIZE-1) {
			if (c == 0x0D || c == 0x0A || c == 0x00) {
				buffer[offset++] = 0x00;
				//read_mode = PLAYING;
				offset = 0;
			} else {
				buffer[offset++] = c;
			}
		} else {
			buffer[BUFFER_SIZE-1] = 0x00;
			//read_mode = PLAYING;
			offset = 0;
		}

		if (c == 0x0D || c == 0x0A || c == 0x00) {
			//read_mode = PLAYING;
			offset = 0;
		}
	}
}

#define DEBOUNCE 0x07
#define DEBOUNCE_DN(x) ((x & DEBOUNCE) == DEBOUNCE)
#define DEBOUNCE_UP(x) ((x | ~DEBOUNCE) == ~DEBOUNCE)

unsigned short volatile b1up   =0;
unsigned short volatile b1state=0;
unsigned short volatile b2up   =0;
unsigned short volatile b2state=0;
unsigned short volatile b3up   =0;
unsigned short volatile b3state=0;

void CheckButtons(void) {
	b1state <<= 1;
	b2state <<= 1;
	b3state <<= 1;

	if ((PDIN & 0x08) != 0x08){
		b1state |= 0x01;
	}

	if ((PFIN & 0x40) != 0x40){
		b2state |= 0x01;
	}

	if ((PFIN & 0x80) != 0x80){
		b3state |= 0x01;
	}
}


void button1_play(void) {
	read_mode = PLAYING;

	SetMatrixBuffer("    ");
	DrawMatrixBuffer();

	play_flight();

	read_mode = READING;
}

void button2_play(void) {
	read_mode = PLAYING;

	SetMatrixBuffer("    ");
	DrawMatrixBuffer();

	play_starwars();

	read_mode = READING;
}

void button3_play(void) {
	read_mode = PLAYING;

	SetMatrixBuffer("    ");
	DrawMatrixBuffer();

	play_string(buffer);

	read_mode = READING;
}

//void main_loop(void) {
//	SetMatrixBuffer("GO!");
//
//	while (read_mode == READING) DrawMatrixBuffer();
//	read_mode = PLAYING;
//
//	SetMatrixBuffer("    ");
//	DrawMatrixBuffer();
//
//	play_string(buffer);
//
//	offset = 0;
//	read_mode = READING;
//}

void main_loop(void) {
	CheckButtons();

	if (DEBOUNCE_DN(b1state)) {
		button1_play();
	}

	if (DEBOUNCE_DN(b2state)) {
		button2_play();
	}

	if (DEBOUNCE_DN(b3state)) {
		button3_play();
	}

}